﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Lavanderia.Entities;
using System.Data.Objects;
using System.Data;

namespace Lavanderia.Repository
{
    public class VentaRepository:MasterRepository,IVentaRepository
    {
        public List<VENTA> GetAllFromVentas()
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasByCriterio(string criterio)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        orderby c.Id descending
                        select c;
            //if (criterio != null && criterio != string.Empty && criterio != "")
            //{
            //    query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
            //            where (c.CLIENTE.ApMaterno.Contains(criterio) ||
            //            c.CLIENTE.ApPaterno.Contains(criterio) ||
            //            c.CLIENTE.Nombre.Contains(criterio) ||
            //            c.CLIENTE.Dni.Contains(criterio) ||
            //            c.CLIENTE.NombreCompleto.Contains(criterio)) && (c.Cancelado == false || c.Cancelado == null)
            //            orderby c.Id descending
            //            select c;
            //}
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasByNComprobante(int ncomp)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        orderby c.Id descending
                        select c;
            if (ncomp != null)
            {
                query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.NCompCli.Equals(ncomp) && (c.Cancelado == false || c.Cancelado == null)
                        orderby c.Id descending
                        select c;
            }
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasByFecha(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        orderby c.Id descending
                        select c;
            if (fecha != null)
            {
                query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where EntityFunctions.TruncateTime(c.Fecha) == fecha && (c.Cancelado == false || c.Cancelado == null)
                        orderby c.Id descending
                        select c;
            }
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasCanceladas()
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == true
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public VENTA GetAllFromVentasById(int id)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Id.Equals(id)
                        select c;
            return query.SingleOrDefault();
        }

        public void AddVentas(VENTA venta)
        {
            foreach (var item in venta.DETALLE_VENTA)
            {
                context.Entry(item.PRODUCTO).State = EntityState.Unchanged;
                item.VENTA = null;
                context.Entry(item).State = EntityState.Added;
            }
            venta.CLIENTE = null;

            context.VENTAs.Add(venta);
            context.SaveChanges();
        }

        public void UpdateVentas(VENTA venta)
        {
            //obtenemos datos de la DB
            var ventaDB = context.VENTAs.Find(venta.Id);
            var detVentaDB = (from c in context.DETALLE_VENTA.Include("PRODUCTO")
                              where c.IdVenta.Equals(venta.Id)
                              select c).ToList();

            List<DETALLE_VENTA> listaProductosEliminadosDB = new List<DETALLE_VENTA>();

            //igualamos los cambios echos y actualizamos los de la DB
            ventaDB.IdCliente = venta.IdCliente;
            ventaDB.Motivo = venta.Motivo;
            ventaDB.NCompCli = venta.NCompCli;
            ventaDB.NCompEmp = venta.NCompEmp;
            ventaDB.Total = venta.Total;
            ventaDB.Fecha = venta.Fecha;
            ventaDB.Acuenta = venta.Acuenta;
            ventaDB.Cancelado = venta.Cancelado;
            ventaDB.Entrega = venta.Entrega;
            ventaDB.Entregado = venta.Entregado;
            ventaDB.FechaEntrega = venta.FechaEntrega;
            ventaDB.Observaciones = venta.Observaciones;
            ventaDB.Pago = venta.Pago;
            ventaDB.Saldo = venta.Saldo;
            ventaDB.TipVenta = venta.TipVenta;
            ventaDB.IdTrabajador = venta.IdTrabajador;

            //verificamos productos q tengan n comun si no agregamos
            foreach (var item in venta.DETALLE_VENTA)
            {
                var existe = ventaDB.DETALLE_VENTA.Where(p => p.IdProducto.Equals(item.IdProducto)).SingleOrDefault();
                if (existe == null)
                {
                    item.VENTA = null;
                    item.PRODUCTO = null;
                    context.Entry(item).State = EntityState.Unchanged;
                    context.DETALLE_VENTA.Add(item);
                }
            }

            //verificamos los productos q esten n la DB por demas
            foreach (var item in ventaDB.DETALLE_VENTA)
            {
                var existe = venta.DETALLE_VENTA.Where(p => p.IdProducto.Equals(item.IdProducto));
                if (existe == null)
                {
                    listaProductosEliminadosDB.Add(item);
                }
            }

            //eliminamos los productos que estan por demas n la DB
            foreach (var item in listaProductosEliminadosDB)
            {
                context.DETALLE_VENTA.Remove(item);
            }

            context.Entry(ventaDB).State = EntityState.Modified;
            context.SaveChanges();
        }

        public void RemoveVentas(int id)
        {
            throw new NotImplementedException();
        }


        public List<VENTA> GetAllFromVentasEntregadas()
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Entregado == true
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasByCriterioAndEntregadas(string criterio)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where (c.Cancelado == false || c.Cancelado == null) && c.Entregado == true
                        select c;
            //if (criterio != null && criterio != string.Empty && criterio != "")
            //{
            //    query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
            //            where (c.CLIENTE.ApMaterno.Contains(criterio) ||
            //            c.CLIENTE.ApPaterno.Contains(criterio) ||
            //            c.CLIENTE.Nombre.Contains(criterio) ||
            //            c.CLIENTE.Dni.Contains(criterio) ||
            //            c.CLIENTE.NombreCompleto.Contains(criterio)) && ((c.Cancelado == false || c.Cancelado == null) && c.Entregado == true)
            //            select c;
            //}
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasByFechaForArqueo(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado==false || c.Cancelado==null
                        select c;
            if (fecha != null)
            {
                query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where EntityFunctions.TruncateTime(c.Fecha) == fecha && (c.Cancelado==false || c.Cancelado==null)
                        select c;
            }
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasByNComprobanteAndEntregadas(int ncomp)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where (c.Cancelado == false || c.Cancelado == null) && c.Entregado == true
                        select c;
            if (ncomp != null)
            {
                query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where (c.NCompCli.Equals(ncomp)) && ((c.Cancelado == false || c.Cancelado == null) && c.Entregado == true)
                        select c;
            }
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasByFechaAndEntregadas(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where (c.Cancelado == false || c.Cancelado == null) && c.Entregado == true
                        select c;
            if (fecha != null)
            {
                query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where (EntityFunctions.TruncateTime(c.Fecha) == fecha) && ((c.Cancelado == false || c.Cancelado == null) && c.Entregado == true)
                        select c;
            }
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasByFechaAbono(DateTime fechaAbono)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        select c;
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasByAllFechas(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Cancelado == false || c.Cancelado == null
                        select c;
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasOfDay(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where EntityFunctions.TruncateTime(c.Fecha) == fecha && (c.Cancelado == false || c.Cancelado == null)
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasOfMonth(int fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Fecha.Month == fecha && (c.Cancelado == false || c.Cancelado == null)
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasOfYear(int fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Fecha.Year == fecha && (c.Cancelado == false || c.Cancelado == null)
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }


        public List<VENTA> GetAllFromVentasCanceladasOfDay(DateTime fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where EntityFunctions.TruncateTime(c.Fecha) == fecha && c.Cancelado == true
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasCanceladasOfMonth(int fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Fecha.Month == fecha && c.Cancelado == true
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }

        public List<VENTA> GetAllFromVentasCanceladasOfYear(int fecha)
        {
            var query = from c in context.VENTAs.Include("CLIENTE").Include("TRABAJADOR")
                        where c.Fecha.Year == fecha && c.Cancelado == true
                        orderby c.Id descending
                        select c;
            return query.ToList();
        }
    }
}
